﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Zhaoxi.SqlSugarAdvanced.CustomSubTable
{
    /// <summary>
    /// 可以根据项目需求，简单修改后-直接使用的自定义分表类
    /// 场景：
    /// 根据区域划分的分表规则：
    /// 省份：每一个省的数据分到同一个表中去
    ///       保存每一个省份的表，以省份的拼音后缀来作为表的名称
    /// </summary>
    public class AreaSubTableService : ISplitTableService
    {
        public static Dictionary<string, string> _AreaDictionary;
        /// <summary>
        /// 自定义分表规则
        /// </summary>
        static AreaSubTableService()
        {
            _AreaDictionary = new Dictionary<string, string>()
            {
                {"Liaoning","辽宁" },
                {"Heilongjiang","黑龙江" },
                {"Jilin","吉林" },
                {"Hebei","河北" },
                {"Henan","河南" },
                {"Shandong","山东" },
                {"Shaanxi","陕西" },
                {"ShanxiS","山西" },
                {"Jiangsu","江苏" },
                {"Zhejiang","浙江" },
                {"Fujian","福建" },
                {"Guangdong","广东" },
                {"Hainan","海南" },
                {"Yunnan","云南" },
                {"Jiangxi","江西" },
                {"Hunan","湖南" },
                {"Hubei","湖北" },
                {"Sichuan","四川" },
                {"Gansu","甘肃" },
                {"Guizhou","贵州" }
            };
        }

        /// <summary>
        /// 获取所有的表--筛选出哪些是要按照这个规则来分表的表 
        /// 通过规则计算，返回的数据记录的就是需要做分表的数据库表
        /// </summary>
        /// <param name="db"></param>
        /// <param name="EntityInfo"></param>
        /// <param name="tableInfos"></param>
        /// <returns></returns>
        public List<SplitTableInfo> GetAllTables(ISqlSugarClient db, EntityInfo EntityInfo, List<DbTableInfo> tableInfos)
        {
            List<SplitTableInfo> result = new List<SplitTableInfo>();
            //var keylist = _AreaDictionary.Select(c => c.Key).ToList();  
            foreach (var item in tableInfos)
            {
                // 判断需要分表的表名称
                if (item.Name.Contains("_Area_")) //区分标识如果不用正则符复杂一些，防止找错表
                {
                    SplitTableInfo data = new SplitTableInfo()
                    {
                        TableName = item.Name //要用item.name不要写错了
                    };
                    result.Add(data);
                }
            }
            return result.OrderBy(it => it.TableName).ToList();//打断点看一下有没有查出所有分表
        }


        /// <summary>
        ///获取字段的值
        /// 操作数据的时候，根据标记的分表字段，把分表字段下的数据 传递过来，根据数据区分数据应该保存到哪个表
        /// </summary>
        /// <param name="db"></param>
        /// <param name="entityInfo"></param>
        /// <param name="splitType"></param>
        /// <param name="entityValue"></param>
        /// <returns></returns>
        public object GetFieldValue(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object entityValue)
        {
            var splitColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyInfo.GetCustomAttribute<SplitFieldAttribute>() != null);
            return splitColumn.PropertyInfo.GetValue(entityValue, null);
        }

        /// <summary>
        /// 确定表名称
        /// </summary>
        /// <param name="db"></param>
        /// <param name="EntityInfo"></param>
        /// <returns></returns>
        public string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo)
        {
            return EntityInfo.DbTableName + "_Area";
        }

        /// <summary>
        /// 获取表名称
        /// </summary>
        /// <param name="db"></param>
        /// <param name="EntityInfo"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo, SplitType type)
        {
            return EntityInfo.DbTableName + "_Area";
        }

        /// <summary>
        /// 获取表名称 - 根据字典拼接表名称
        /// </summary>
        /// <param name="db"></param>
        /// <param name="entityInfo"></param>
        /// <param name="splitType"></param>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object fieldValue)
        {
            KeyValuePair<string, string> keyPar = _AreaDictionary.FirstOrDefault(c => fieldValue.ToString().Contains(c.Value));
            return entityInfo.DbTableName + "_Area_" + keyPar.Key; //根据值按首字母
        }
    }
}
